use axum::{
    extract::{Request},
    response::Response,
    body::Bytes,

};
use axum_login::AuthSession;

use crate::users::Backend;
use axum_casbin::{CasbinVals};
use std::{
    task::{Poll},
};
use http_body::Body;

use std::error::Error as StdError; 

// 自定义身份验证中间件，用于注入 CasbinVals
#[derive(Clone)]
pub struct AuthInjectLayer;

impl<S> tower::Layer<S> for AuthInjectLayer {
    type Service = AuthInjectMiddleware<S>;
    
    fn layer(&self, inner: S) -> Self::Service {
        AuthInjectMiddleware { inner }
    }
}

#[derive(Clone)]
pub struct AuthInjectMiddleware<S> {
    inner: S,
}
// 你的 casbinauthz.rs 中，确保 AuthInjectMiddleware 正确处理 AuthSession
impl<S, ReqBody, ResBody> tower::Service<Request<ReqBody>> for AuthInjectMiddleware<S>
where
    S: tower::Service<Request<ReqBody>, Response = Response<ResBody>> + Clone + Send + 'static,
    S::Future: Send + 'static,
    ReqBody: Send + 'static,
    ResBody: Body<Data = Bytes> + Send + 'static,
    ResBody::Error: Into<Box<dyn StdError + Send + Sync>>,
{
    type Response = S::Response;
    type Error = S::Error;
    type Future = futures::future::BoxFuture<'static, Result<Self::Response, Self::Error>>;
    
    fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
        self.inner.poll_ready(cx)
    }
    
    fn call(&mut self, mut req: Request<ReqBody>) -> Self::Future {
        let mut inner = self.inner.clone();
        Box::pin(async move {
            // 打印请求路径，确认是否包含 /adduser
            let path = req.uri().path().to_string();
            println!("[AuthInject] 处理请求: {}", path);

            // 提取 AuthSession
            let session = req.extensions().get::<AuthSession<Backend>>();
            if session.is_none() {
                println!("[AuthInject] 警告：未找到 AuthSession，无法获取用户信息");
            } else {
                println!("[AuthInject] 找到 AuthSession");
            }

            // 提取用户名并注入 CasbinVals
            let username = session
                .and_then(|s| s.user.as_ref())
                .map(|u| u.username.clone());

            if let Some(username) = &username {
                let vals = CasbinVals {
                    subject: username.clone(),
                    domain: None,
                };
                req.extensions_mut().insert(vals);
                println!("[AuthInject] 已注入 CasbinVals（用户: {}）", username);
            } else {
                let vals = CasbinVals {
                    subject: "anonymous".to_string(),
                    domain: None,
                };
                req.extensions_mut().insert(vals);
                println!("[AuthInject] 已注入匿名 CasbinVals");
            }

            inner.call(req).await
        })
    }
}
